#ifndef _CONFIG_HPP_
#define _CONFIG_HPP_
#include "defs.h"
#include <array>
#include <string>
// 定常  暂时直接赋值
class Config
{
  private:
    Equation_t equsType{Equation_t::NavierStokes};
    bool restart{false};
    real_t
        // euler
        // reynoldsNumber{5000.0},
        // reynoldsLength{1.0},
        // machNumber{0.8},
        // TempInf{288.0},

        reynoldsNumber{500000.0},
        reynoldsLength{1.0},
        machNumber{0.2},
        TempInf{288.15},
        // pressure 是 euler需要的  Ns 方程不予理睬
        pressureInf{1.0E+5},
        angleAttack{0.0};

    Nondim_t nondimType{Nondim_t::DIMENSIONAL};

    real_t refMomentX{0.25},
        refMomentY{0.0},
        //  Reference length for moment non-dimensional coefficients
        refLength{1.0};

    ConvectFlux_t convFluxType{ConvectFlux_t::Roe1};

    TimeDiscrete_t timeDiscType{TimeDiscrete_t::RUNGE_KUTTA_EXPLICIT};

    int numStage{5};
    real_t cflNum{2.5};
    std::array<real_t, 5> stageCoef{0.0533, 0.1263, 0.2375, 0.4414, 1.000},
        dissBlendCoef{1.00, 1.00, 1.00, 1.00, 1.00},
        dissEvalu{1, 1, 1, 1, 1};

    TimeStep_t timeStepType{TimeStep_t::Local};

    int extIter{99999};
    real_t resReduct{2.0},
        convTol{-2.0};
    Limiter_t limiter{Limiter_t::NONE};
    real_t limiterCoef{100.0},
        entropyFixCoef{0.05};

    int pressureExtrNum{3};
    // max. rel. change of rho and rho*E at dummy cells of slip walls
    real_t maxSlipWallChg{1.0};

    std::string configFname{"fplate.cfg"},
        meshFname{"real_plate.x"},
        boundFname{"real_plate.inp"};

    MeshFormat_t meshFormat{MeshFormat_t::ASSCII};
    OutputFormat_t outputFormat{OutputFormat_t::Tec_ASSCII};

    std::string convgFname{"history.dat"},
        restartInFname{"restart_flow.dat"},
        restartOutFname{"restart_flow.dat"},
        // 将会添加 .dat 后缀后输出流场迭代的编号
        flowSolFname{"real_plate_flow"},
        surfFlowFname{"real_plate_surface"};

    int wrtSolFreq{1000},
        wrtConvFreq{20};

  public:
    // 先不从文件中读，降低工作量，有时间再补上
    Config(){};
    Config(const Config &src) = delete;
    Config(Config &&src) = delete;
    Config &operator=(const Config &src) = delete;
    Config &operator=(Config &&src) = delete;
    ~Config() = default;

    const Equation_t GetEquationType() const { return equsType; }

    const bool GetRestartTag() const { return restart; }

    const real_t GetReynoldsNumber() const { return reynoldsNumber; }

    const real_t GetReynoldsLength() const { return reynoldsLength; }

    const real_t GetMachNumber() const { return machNumber; }

    const real_t GetTemperatureInf() const { return TempInf; }

    const real_t GetPressureInf() const { return pressureInf; }

    const real_t GetAngleAttack() const { return angleAttack; }

    const Nondim_t GetNondimType() const { return nondimType; }

    const real_t GetRefMomentX() const { return refMomentX; }

    const real_t GetRefMomentY() const { return refMomentY; }

    const real_t GetRefLength() const { return refLength; }

    const ConvectFlux_t GetConvectFluxType() const { return convFluxType; }

    const TimeDiscrete_t GetTimeDiscType() const { return timeDiscType; }

    const int GetNumStage() const { return numStage; }

    const real_t GetCflNum() const { return cflNum; }

    const std::array<real_t, 5> &GetStageCoef() const { return stageCoef; }

    const std::array<real_t, 5> &GetDissBlendCoef() const { return dissBlendCoef; }

    const std::array<real_t, 5> &GetDissEvalu() const { return dissEvalu; }

    const TimeStep_t GetTimeStepType() const { return timeStepType; }

    const int GetExtIter() const { return extIter; }

    const real_t GetResReduct() const { return resReduct; }

    const real_t GetConvTol() const { return convTol; }

    const Limiter_t GetLimiter() const { return limiter; }

    const real_t GetLimiterCoef() const { return limiterCoef; }

    const real_t GetEntropyFixCoef() const { return entropyFixCoef; }

    const int GetPressureExtrNum() const { return pressureExtrNum; }

    const real_t GetMaxSlipWallChg() const { return maxSlipWallChg; }

    const std::string &GetConfigFname() const { return configFname; }

    const std::string &GetMeshFname() const { return meshFname; }

    const std::string &GetBoundFname() const { return boundFname; }

    const MeshFormat_t GetMeshFormat() const { return meshFormat; }

    const OutputFormat_t GetOutputFormat() const { return outputFormat; }

    const std::string &GetConvgFname() const { return convgFname; }

    const std::string &GetRestartInFname() const { return restartInFname; }

    const std::string &GetRestartOutFname() const { return restartOutFname; }

    const std::string &GetFlowSolFname() const { return flowSolFname; }

    const std::string &GetSurfFlowFname() const { return surfFlowFname; }

    const int GetWrtSolFreq() const { return wrtSolFreq; }

    const int GetWrtConvFreq() const { return wrtConvFreq; }
};

#endif